<template xmlns="http://www.w3.org/1999/html">
  <div class="ai-chat-container">

    <div class="chat-messages">
      <div v-for="(message, index) in messages" :key="index" class="message" :class="message.type">
        <div class="message-content">
          {{ message.content }}
        </div>
      </div>
      <div v-if="isLoading" class="message ai">
        <div class="message-content">
          <span v-if="streamResponse">{{ streamResponse }}</span>
          <span v-else>思考中...</span>
          <span class="typing-indicator">...</span>
        </div>
      </div>
    </div>


    <div class="input-area">
      <input
          v-model="userInput"
          @keyup.enter="sendMessage"
          placeholder="输入你的问题..."
          :disabled="isLoading"
      />
      <button @click="sendMessage" :disabled="isLoading || !userInput.trim()">
        {{ isLoading ? '发送中...' : '发送' }}
      </button>
    </div>
    <div>
      <input type="checkbox" v-model="isStream" value="true">
      <label >流式响应</label>

      <input v-model="dialogId" placeholder="输入对话ID" />
      <label >会话id</label>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import request from "@/util/request.js";

const dialogId = ref('');
const userInput = ref('');
const messages = ref([]);
const isLoading = ref(false);
const streamResponse = ref('');
const controller = ref(null); // 用于取消请求的 AbortController
const isStream = ref(true);

const headers = {
  'Content-Type': 'application/json',
  'Authorization' :'Bearer eyJhbGciOiJIUzI1NiJ9.eyJwaG9uZSI6IjE3NjY3Mzk5MTkzIiwiaWQiOjgsImlhdCI6MTc0NjQzNzA5OCwiZXhwIjoxNzQ2NTIzNDk4fQ.nD3M3SBAWCbjw3IoTWQYvMLeAvMeupYrkd8M5zHJDoA'
}

function decodeMixedString(str) {
  return str.replace(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}/g, (match) => {
    if (match.startsWith('\\u')) {
      return String.fromCharCode(parseInt(match.slice(2), 16));
    } else if (match.startsWith('\\x')) {
      return String.fromCharCode(parseInt(match.slice(2), 16));
    }
    return match;
  });
}

const sendMessage = async () => {

  if (!userInput.value.trim() || isLoading.value) return;

  // 添加用户消息
  messages.value.push({
    type: 'user',
    content: userInput.value
  });

  const currentInput = userInput.value;
  userInput.value = '';
  isLoading.value = true;
  streamResponse.value = '';

  try {
    // 创建 AbortController 以便可以取消请求
    controller.value = new AbortController();

    if (isStream.value) {
      // 使用 EventSource 或 fetch 实现流式响应
      const response = await fetch('http://localhost:8080/aichat/ask/stream', {
        method: 'POST',
        headers: headers,
        body: JSON.stringify({
          dialogId: dialogId.value,
          ask: currentInput,
        }),
        signal: controller.value.signal
      });

      if (!response.ok) {
        throw new Error('请求失败');
      }

      // 处理流式响应
      const reader = response.body.getReader();
      const decoder = new TextDecoder();

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        const chunk = decoder.decode(value, { stream: true });
        streamResponse.value += JSON.parse(decodeMixedString(chunk).substring(5))['content'];
      }

    }else{
      const response = await request({
        method: 'POST',
        url: '/aichat/ask',
        headers: headers,
        data: {
          dialogId: dialogId.value,
          ask: currentInput,
        }
      })
      streamResponse.value = response.data.response;
    }

    // 流结束后添加到消息列表
    messages.value.push({
      type: 'ai',
      content: streamResponse.value
    });

  } catch (error) {
    if (error.name !== 'AbortError') {
      console.error('请求出错:', error);
      messages.value.push({
        type: 'ai',
        content: '抱歉，出错了: ' + error.message
      });
    }
  } finally {
    isLoading.value = false;
    streamResponse.value = '';
    controller.value = null;
  }
};

// 取消当前请求的函数
const cancelRequest = () => {
  if (controller.value) {
    controller.value.abort();
    isLoading.value = false;
    streamResponse.value = '';

    // 如果用户想取消，可以添加一条消息
    messages.value.push({
      type: 'ai',
      content: '请求已取消'
    });
  }
};
</script>

<style scoped>
.ai-chat-container {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background-color: #f9f9f9;
}

.chat-messages {
  height: 500px;
  overflow-y: auto;
  margin-bottom: 20px;
  padding: 10px;
  background-color: white;
  border-radius: 4px;
}

.message {
  margin-bottom: 15px;
  padding: 10px 15px;
  border-radius: 18px;
  max-width: 80%;
}

.message.user {
  margin-left: auto;
  background-color: #007bff;
  color: white;
  border-bottom-right-radius: 4px;
}

.message.ai {
  margin-right: auto;
  background-color: #f1f1f1;
  color: #333;
  border-bottom-left-radius: 4px;
}

.message-content {
  white-space: pre-wrap;
  word-wrap: break-word;
}

.input-area {
  display: flex;
  gap: 10px;
}

.input-area input {
  flex-grow: 1;
  padding: 10px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.input-area button {
  padding: 10px 20px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.input-area button:disabled {
  background-color: #cccccc;
  cursor: not-allowed;
}

.typing-indicator {
  animation: blink 1.4s infinite;
  opacity: 0.6;
}

@keyframes blink {
  0%, 100% { opacity: 0.6; }
  50% { opacity: 0.1; }
}
</style>